#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
🤖 AIOT智能学习桌完整系统 (v2.0 旗舰版)

系统架构：
┌─────────────────────────────────────────────────────────────┐
│                    智能学习桌主控系统                         │
├─────────────────────────────────────────────────────────────┤
│  硬件层: EBP3901 + 传感器 + 摄像头 + 音频 + 显示            │
│  通信层: 串口 + WiFi + WebSocket + HTTP API                 │
│  智能层: AI分析 + 语音识别 + 坐姿检测 + 疲劳监测            │
│  应用层: 微信小程序 + 数据存储 + 报告生成 + 个性化建议       │
└─────────────────────────────────────────────────────────────┘

核心功能：
✅ 多传感器融合坐姿监测 (超声波 + 摄像头)
✅ AI智能语音交互系统 (ChatGPT集成)
✅ 实时疲劳检测和休息提醒
✅ 个性化学习建议生成
✅ 微信小程序数据同步
✅ 完整的数据存储和分析
✅ 智能时间管理
✅ 健康报告生成

作者: AIOT智能学习桌项目组
版本: v2.0
日期: 2024
"""

import sys
import os
import time
import json
import asyncio
import logging
import threading
import queue
import sqlite3
import serial
import requests
import websockets
import schedule
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, asdict
from collections import deque
import numpy as np
import cv2

# 导入子模块
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from 摄像头坐姿检测模块.camera_posture import CameraPostureDetector, PostureConfig
from config import *

# 配置日志系统
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('logs/smart_desk_system.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# ========== 系统配置 ==========
@dataclass
class SystemConfig:
    """系统配置类"""
    # 硬件配置
    SERIAL_PORT: str = 'COM5'
    SERIAL_BAUDRATE: int = 115200
    CAMERA_ID: int = 0
    
    # 网络配置
    WECHAT_WEBSOCKET_URL: str = 'ws://localhost:8080/smartdesk'
    API_SERVER_HOST: str = 'localhost'
    API_SERVER_PORT: int = 8000
    
    # AI配置
    OPENAI_API_KEY: str = 'your-openai-api-key'
    OPENAI_API_URL: str = 'https://api.openai.com/v1/chat/completions'
    TTS_API_URL: str = 'https://api.openai.com/v1/audio/speech'
    
    # 数据库配置
    DATABASE_PATH: str = 'data/smart_desk.db'
    BACKUP_INTERVAL: int = 3600  # 备份间隔(秒)
    
    # 系统参数
    DETECTION_INTERVAL: float = 1.0     # 检测间隔(秒)
    WARNING_COOLDOWN: float = 30.0      # 警告冷却时间(秒)
    SESSION_TIMEOUT: float = 1800.0     # 会话超时时间(秒)
    
    # 坐姿阈值
    IDEAL_DISTANCE_MIN: float = 30.0    # 理想距离最小值(cm)
    IDEAL_DISTANCE_MAX: float = 50.0    # 理想距离最大值(cm)
    POSTURE_SCORE_THRESHOLD: float = 70.0  # 坐姿得分阈值

# ========== 数据结构定义 ==========
@dataclass
class SystemStatus:
    """系统状态"""
    is_running: bool = False
    user_present: bool = False
    current_session_id: str = ""
    session_start_time: float = 0
    total_study_time: float = 0
    posture_warnings: int = 0
    voice_interactions: int = 0
    camera_enabled: bool = True
    voice_enabled: bool = True
    wifi_connected: bool = False
    last_activity_time: float = 0

@dataclass
class PostureData:
    """坐姿数据"""
    ultrasonic_distance: float
    camera_score: float
    combined_score: float
    status: str
    issues: List[str]
    suggestions: List[str]
    need_warning: bool
    timestamp: float

@dataclass
class VoiceInteraction:
    """语音交互记录"""
    session_id: str
    user_input: str
    ai_response: str
    confidence: float
    timestamp: float
    response_time: float

@dataclass
class StudySession:
    """学习会话"""
    session_id: str
    start_time: float
    end_time: float
    duration: float
    posture_warnings: int
    voice_interactions: int
    average_posture_score: float
    fatigue_events: int
    break_recommendations: int

# ========== 数据库管理器 ==========
class DatabaseManager:
    """数据库管理器"""
    
    def __init__(self, db_path: str):
        self.db_path = db_path
        self.init_database()
    
    def init_database(self):
        """初始化数据库"""
        os.makedirs(os.path.dirname(self.db_path), exist_ok=True)
        
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            
            # 创建用户表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    user_id TEXT UNIQUE,
                    name TEXT,
                    age INTEGER,
                    height REAL,
                    preferences TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # 创建学习会话表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS study_sessions (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    session_id TEXT UNIQUE,
                    user_id TEXT,
                    start_time REAL,
                    end_time REAL,
                    duration REAL,
                    posture_warnings INTEGER,
                    voice_interactions INTEGER,
                    average_posture_score REAL,
                    fatigue_events INTEGER,
                    break_recommendations INTEGER,
                    notes TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # 创建坐姿记录表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS posture_records (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    session_id TEXT,
                    ultrasonic_distance REAL,
                    camera_score REAL,
                    combined_score REAL,
                    status TEXT,
                    issues TEXT,
                    suggestions TEXT,
                    need_warning BOOLEAN,
                    timestamp REAL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # 创建语音交互表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS voice_interactions (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    session_id TEXT,
                    user_input TEXT,
                    ai_response TEXT,
                    confidence REAL,
                    response_time REAL,
                    timestamp REAL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # 创建系统日志表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS system_logs (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    level TEXT,
                    message TEXT,
                    module TEXT,
                    timestamp REAL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            # 创建健康报告表
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS health_reports (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    user_id TEXT,
                    report_date DATE,
                    total_study_time REAL,
                    average_posture_score REAL,
                    posture_warnings INTEGER,
                    fatigue_score REAL,
                    recommendations TEXT,
                    improvements TEXT,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            
            conn.commit()
        
        logger.info("📊 数据库初始化完成")
    
    def save_study_session(self, session: StudySession):
        """保存学习会话"""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            cursor.execute('''
                INSERT OR REPLACE INTO study_sessions 
                (session_id, start_time, end_time, duration, posture_warnings, 
                 voice_interactions, average_posture_score, fatigue_events, break_recommendations)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                session.session_id, session.start_time, session.end_time, session.duration,
                session.posture_warnings, session.voice_interactions, session.average_posture_score,
                session.fatigue_events, session.break_recommendations
            ))
            conn.commit()
    
    def save_posture_record(self, record: PostureData, session_id: str):
        """保存坐姿记录"""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            cursor.execute('''
                INSERT INTO posture_records 
                (session_id, ultrasonic_distance, camera_score, combined_score, 
                 status, issues, suggestions, need_warning, timestamp)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                session_id, record.ultrasonic_distance, record.camera_score, record.combined_score,
                record.status, json.dumps(record.issues), json.dumps(record.suggestions),
                record.need_warning, record.timestamp
            ))
            conn.commit()
    
    def save_voice_interaction(self, interaction: VoiceInteraction):
        """保存语音交互"""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            cursor.execute('''
                INSERT INTO voice_interactions 
                (session_id, user_input, ai_response, confidence, response_time, timestamp)
                VALUES (?, ?, ?, ?, ?, ?)
            ''', (
                interaction.session_id, interaction.user_input, interaction.ai_response,
                interaction.confidence, interaction.response_time, interaction.timestamp
            ))
            conn.commit()
    
    def get_user_statistics(self, user_id: str, days: int = 7) -> Dict:
        """获取用户统计数据"""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.cursor()
            
            start_time = time.time() - (days * 24 * 3600)
            
            # 获取基本统计
            cursor.execute('''
                SELECT 
                    COUNT(*) as session_count,
                    COALESCE(SUM(duration), 0) as total_study_time,
                    COALESCE(AVG(average_posture_score), 0) as avg_posture_score,
                    COALESCE(SUM(posture_warnings), 0) as total_warnings,
                    COALESCE(SUM(voice_interactions), 0) as total_interactions
                FROM study_sessions 
                WHERE user_id = ? AND start_time >= ?
            ''', (user_id, start_time))
            
            stats = cursor.fetchone()
            
            # 获取每日数据
            cursor.execute('''
                SELECT 
                    DATE(datetime(start_time, 'unixepoch')) as date,
                    SUM(duration) as daily_study_time,
                    AVG(average_posture_score) as daily_posture_score,
                    SUM(posture_warnings) as daily_warnings
                FROM study_sessions 
                WHERE user_id = ? AND start_time >= ?
                GROUP BY DATE(datetime(start_time, 'unixepoch'))
                ORDER BY date DESC
            ''', (user_id, start_time))
            
            daily_data = cursor.fetchall()
            
            return {
                'session_count': stats[0],
                'total_study_time': stats[1],
                'average_posture_score': stats[2],
                'total_warnings': stats[3],
                'total_interactions': stats[4],
                'daily_data': [
                    {
                        'date': row[0],
                        'study_time': row[1],
                        'posture_score': row[2],
                        'warnings': row[3]
                    } for row in daily_data
                ]
            }

# ========== AI分析引擎 ==========
class AIAnalysisEngine:
    """AI分析引擎"""
    
    def __init__(self, config: SystemConfig):
        self.config = config
        self.conversation_history = deque(maxlen=10)
    
    def analyze_posture_trend(self, posture_records: List[PostureData]) -> Dict:
        """分析坐姿趋势"""
        if not posture_records:
            return {'trend': 'stable', 'analysis': '数据不足'}
        
        # 计算趋势
        scores = [record.combined_score for record in posture_records[-20:]]
        if len(scores) < 5:
            return {'trend': 'stable', 'analysis': '数据不足'}
        
        # 简单线性回归分析趋势
        x = np.arange(len(scores))
        z = np.polyfit(x, scores, 1)
        slope = z[0]
        
        if slope > 2:
            trend = 'improving'
            analysis = '坐姿呈改善趋势，请继续保持'
        elif slope < -2:
            trend = 'declining'
            analysis = '坐姿呈下降趋势，请注意调整'
        else:
            trend = 'stable'
            analysis = '坐姿保持稳定状态'
        
        return {
            'trend': trend,
            'analysis': analysis,
            'slope': slope,
            'recent_average': np.mean(scores[-5:]),
            'overall_average': np.mean(scores)
        }
    
    def generate_personalized_advice(self, user_stats: Dict, posture_trend: Dict) -> List[str]:
        """生成个性化建议"""
        advice = []
        
        # 基于学习时间的建议
        if user_stats['total_study_time'] > 4 * 3600:  # 超过4小时
            advice.append("学习时间较长，建议每小时休息10-15分钟")
        
        # 基于坐姿评分的建议
        if user_stats['average_posture_score'] < 70:
            advice.append("坐姿需要改善，建议调整座椅高度和距离")
        
        # 基于警告次数的建议
        warning_rate = user_stats['total_warnings'] / max(user_stats['session_count'], 1)
        if warning_rate > 5:
            advice.append("坐姿警告较多，建议加强坐姿意识训练")
        
        # 基于趋势的建议
        if posture_trend['trend'] == 'declining':
            advice.append("坐姿趋势下降，建议重新调整学习环境")
        elif posture_trend['trend'] == 'improving':
            advice.append("坐姿改善明显，请继续保持良好习惯")
        
        if not advice:
            advice.append("保持当前良好状态，注意劳逸结合")
        
        return advice
    
    def chat_with_ai(self, user_input: str, context: Dict = None) -> str:
        """与AI对话"""
        try:
            # 构建对话上下文
            messages = [
                {
                    "role": "system",
                    "content": "你是一个智能学习桌的AI助手。请根据用户的坐姿数据和学习情况，提供专业、友好的建议。回复要简洁明了，不超过100字。"
                }
            ]
            
            # 添加历史对话
            for msg in self.conversation_history:
                messages.append(msg)
            
            # 添加上下文信息
            if context:
                context_info = f"用户当前状态：坐姿得分{context.get('posture_score', 0):.1f}，学习时长{context.get('study_time', 0):.1f}分钟"
                messages.append({"role": "system", "content": context_info})
            
            # 添加用户输入
            messages.append({"role": "user", "content": user_input})
            
            # 调用AI API
            response = requests.post(
                self.config.OPENAI_API_URL,
                headers={
                    'Authorization': f'Bearer {self.config.OPENAI_API_KEY}',
                    'Content-Type': 'application/json'
                },
                json={
                    'model': 'gpt-3.5-turbo',
                    'messages': messages,
                    'max_tokens': 150,
                    'temperature': 0.7
                },
                timeout=10
            )
            
            if response.status_code == 200:
                ai_response = response.json()['choices'][0]['message']['content']
                
                # 更新对话历史
                self.conversation_history.append({"role": "user", "content": user_input})
                self.conversation_history.append({"role": "assistant", "content": ai_response})
                
                return ai_response
            else:
                return "抱歉，暂时无法连接到AI服务，请稍后再试。"
                
        except Exception as e:
            logger.error(f"❌ AI对话失败: {e}")
            return "抱歉，AI服务暂时不可用。"

# ========== 微信小程序接口 ==========
class WeChatInterface:
    """微信小程序接口"""
    
    def __init__(self, config: SystemConfig):
        self.config = config
        self.websocket = None
        self.connected = False
        self.message_queue = queue.Queue()
    
    async def connect(self):
        """连接到微信小程序后端"""
        try:
            self.websocket = await websockets.connect(self.config.WECHAT_WEBSOCKET_URL)
            self.connected = True
            logger.info("📱 微信小程序连接成功")
            
            # 启动消息处理循环
            asyncio.create_task(self.message_handler())
            
        except Exception as e:
            logger.error(f"❌ 微信小程序连接失败: {e}")
            self.connected = False
    
    async def message_handler(self):
        """消息处理循环"""
        try:
            async for message in self.websocket:
                data = json.loads(message)
                await self.handle_message(data)
        except Exception as e:
            logger.error(f"❌ 微信消息处理异常: {e}")
            self.connected = False
    
    async def handle_message(self, data: Dict):
        """处理收到的消息"""
        message_type = data.get('type')
        
        if message_type == 'user_command':
            # 用户指令
            command = data.get('command')
            await self.process_user_command(command)
        elif message_type == 'get_status':
            # 获取状态
            await self.send_system_status()
        elif message_type == 'get_statistics':
            # 获取统计数据
            user_id = data.get('user_id', 'default')
            days = data.get('days', 7)
            await self.send_user_statistics(user_id, days)
        elif message_type == 'voice_message':
            # 语音消息
            text = data.get('text')
            self.message_queue.put(('voice_input', text))
    
    async def process_user_command(self, command: str):
        """处理用户指令"""
        if command == 'start_session':
            self.message_queue.put(('start_session', None))
        elif command == 'end_session':
            self.message_queue.put(('end_session', None))
        elif command == 'get_advice':
            self.message_queue.put(('get_advice', None))
        elif command == 'calibrate':
            self.message_queue.put(('calibrate', None))
    
    async def send_message(self, data: Dict):
        """发送消息到微信小程序"""
        if self.connected and self.websocket:
            try:
                await self.websocket.send(json.dumps(data))
            except Exception as e:
                logger.error(f"❌ 发送微信消息失败: {e}")
    
    async def send_realtime_data(self, posture_data: PostureData, system_status: SystemStatus):
        """发送实时数据"""
        data = {
            'type': 'realtime_data',
            'posture': asdict(posture_data),
            'system': asdict(system_status),
            'timestamp': time.time()
        }
        await self.send_message(data)
    
    async def send_warning(self, warning_type: str, message: str, suggestions: List[str]):
        """发送警告消息"""
        data = {
            'type': 'warning',
            'warning_type': warning_type,
            'message': message,
            'suggestions': suggestions,
            'timestamp': time.time()
        }
        await self.send_message(data)
    
    async def send_system_status(self):
        """发送系统状态"""
        # 这里需要从主系统获取状态
        pass
    
    async def send_user_statistics(self, user_id: str, days: int):
        """发送用户统计数据"""
        # 这里需要从数据库获取统计数据
        pass

# ========== 硬件通信管理器 ==========
class HardwareCommunicator:
    """硬件通信管理器"""
    
    def __init__(self, config: SystemConfig):
        self.config = config
        self.serial_connection = None
        self.connected = False
        self.message_queue = queue.Queue()
        self.response_handlers = {}
    
    def connect(self) -> bool:
        """连接到硬件"""
        try:
            self.serial_connection = serial.Serial(
                port=self.config.SERIAL_PORT,
                baudrate=self.config.SERIAL_BAUDRATE,
                timeout=1
            )
            self.connected = True
            logger.info("🔌 硬件连接成功")
            
            # 启动消息处理线程
            threading.Thread(target=self.message_handler, daemon=True).start()
            
            return True
        except Exception as e:
            logger.error(f"❌ 硬件连接失败: {e}")
            return False
    
    def message_handler(self):
        """消息处理循环"""
        while self.connected:
            try:
                if self.serial_connection.in_waiting:
                    message = self.serial_connection.readline().decode().strip()
                    self.process_hardware_message(message)
                time.sleep(0.01)
            except Exception as e:
                logger.error(f"❌ 硬件消息处理异常: {e}")
                time.sleep(1)
    
    def process_hardware_message(self, message: str):
        """处理硬件消息"""
        try:
            if message.startswith("POSTURE_DATA:"):
                data = json.loads(message[13:])
                self.message_queue.put(('posture_data', data))
            elif message.startswith("VOICE_INPUT:"):
                text = message[12:]
                self.message_queue.put(('voice_input', text))
            elif message.startswith("BUTTON_PRESS:"):
                button = message[13:]
                self.message_queue.put(('button_press', button))
            elif message.startswith("SYSTEM_STATUS:"):
                data = json.loads(message[14:])
                self.message_queue.put(('system_status', data))
        except Exception as e:
            logger.error(f"❌ 硬件消息解析失败: {e}")
    
    def send_command(self, command: str, data: Dict = None):
        """发送命令到硬件"""
        if not self.connected:
            return False
        
        try:
            if data:
                message = f"{command}:{json.dumps(data)}\n"
            else:
                message = f"{command}\n"
            
            self.serial_connection.write(message.encode())
            return True
        except Exception as e:
            logger.error(f"❌ 发送硬件命令失败: {e}")
            return False
    
    def send_voice_response(self, text: str):
        """发送语音响应"""
        return self.send_command("VOICE_RESPONSE", {"text": text})
    
    def send_warning(self, warning_type: str, message: str):
        """发送警告"""
        return self.send_command("WARNING", {"type": warning_type, "message": message})
    
    def request_status(self):
        """请求系统状态"""
        return self.send_command("GET_STATUS")

# ========== 主系统控制器 ==========
class SmartDeskSystem:
    """智能学习桌主系统"""
    
    def __init__(self, config: SystemConfig = None):
        self.config = config or SystemConfig()
        
        # 初始化组件
        self.db_manager = DatabaseManager(self.config.DATABASE_PATH)
        self.ai_engine = AIAnalysisEngine(self.config)
        self.wechat_interface = WeChatInterface(self.config)
        self.hardware_comm = HardwareCommunicator(self.config)
        self.camera_detector = None
        
        # 系统状态
        self.system_status = SystemStatus()
        self.current_session = None
        self.posture_history = deque(maxlen=100)
        self.voice_interactions = deque(maxlen=50)
        
        # 控制变量
        self.running = False
        self.last_warning_time = 0
        self.last_backup_time = 0
        
        logger.info("🤖 智能学习桌系统初始化完成")
    
    async def start(self):
        """启动系统"""
        logger.info("🚀 启动智能学习桌系统...")
        
        # 连接硬件
        if not self.hardware_comm.connect():
            logger.error("❌ 硬件连接失败，系统无法启动")
            return False
        
        # 连接微信小程序
        await self.wechat_interface.connect()
        
        # 初始化摄像头检测器
        try:
            self.camera_detector = CameraPostureDetector()
            if not self.camera_detector.start_detection():
                logger.warning("⚠️ 摄像头检测启动失败，将仅使用超声波检测")
                self.camera_detector = None
        except Exception as e:
            logger.warning(f"⚠️ 摄像头模块加载失败: {e}")
            self.camera_detector = None
        
        # 设置定时任务
        self.setup_scheduled_tasks()
        
        # 更新系统状态
        self.system_status.is_running = True
        self.system_status.wifi_connected = self.wechat_interface.connected
        self.system_status.camera_enabled = self.camera_detector is not None
        
        # 启动主循环
        self.running = True
        asyncio.create_task(self.main_loop())
        
        logger.info("✅ 智能学习桌系统启动成功")
        return True
    
    def setup_scheduled_tasks(self):
        """设置定时任务"""
        # 每小时生成健康报告
        schedule.every().hour.do(self.generate_hourly_report)
        
        # 每天生成日报
        schedule.every().day.at("23:59").do(self.generate_daily_report)
        
        # 定期数据备份
        schedule.every(self.config.BACKUP_INTERVAL).seconds.do(self.backup_data)
        
        # 定期清理过期数据
        schedule.every().week.do(self.cleanup_old_data)
    
    async def main_loop(self):
        """主控制循环"""
        while self.running:
            try:
                # 处理硬件消息
                self.process_hardware_messages()
                
                # 处理微信消息
                self.process_wechat_messages()
                
                # 更新系统状态
                self.update_system_status()
                
                # 检查会话超时
                self.check_session_timeout()
                
                # 执行定时任务
                schedule.run_pending()
                
                # 发送实时数据
                if self.current_session and self.posture_history:
                    latest_posture = self.posture_history[-1]
                    await self.wechat_interface.send_realtime_data(latest_posture, self.system_status)
                
                await asyncio.sleep(0.1)
                
            except Exception as e:
                logger.error(f"❌ 主循环异常: {e}")
                await asyncio.sleep(1)
    
    def process_hardware_messages(self):
        """处理硬件消息"""
        while not self.hardware_comm.message_queue.empty():
            try:
                message_type, data = self.hardware_comm.message_queue.get_nowait()
                
                if message_type == 'posture_data':
                    self.handle_posture_data(data)
                elif message_type == 'voice_input':
                    asyncio.create_task(self.handle_voice_input(data))
                elif message_type == 'button_press':
                    self.handle_button_press(data)
                elif message_type == 'system_status':
                    self.handle_system_status_update(data)
                    
            except queue.Empty:
                break
            except Exception as e:
                logger.error(f"❌ 处理硬件消息异常: {e}")
    
    def process_wechat_messages(self):
        """处理微信消息"""
        while not self.wechat_interface.message_queue.empty():
            try:
                message_type, data = self.wechat_interface.message_queue.get_nowait()
                
                if message_type == 'voice_input':
                    asyncio.create_task(self.handle_voice_input(data))
                elif message_type == 'start_session':
                    self.start_new_session()
                elif message_type == 'end_session':
                    self.end_current_session()
                elif message_type == 'get_advice':
                    asyncio.create_task(self.send_personalized_advice())
                elif message_type == 'calibrate':
                    self.calibrate_system()
                    
            except queue.Empty:
                break
            except Exception as e:
                logger.error(f"❌ 处理微信消息异常: {e}")
    
    def handle_posture_data(self, data: Dict):
        """处理坐姿数据"""
        try:
            posture_data = PostureData(
                ultrasonic_distance=data.get('ultrasonic_distance', 0),
                camera_score=data.get('camera_score', 0),
                combined_score=data.get('combined_score', 0),
                status=data.get('status', 'unknown'),
                issues=data.get('issues', []),
                suggestions=data.get('suggestions', []),
                need_warning=data.get('need_warning', False),
                timestamp=time.time()
            )
            
            # 添加到历史记录
            self.posture_history.append(posture_data)
            
            # 保存到数据库
            if self.current_session:
                self.db_manager.save_posture_record(posture_data, self.current_session.session_id)
            
            # 检查是否需要警告
            if posture_data.need_warning and self.should_give_warning():
                asyncio.create_task(self.send_posture_warning(posture_data))
            
            # 更新用户状态
            self.system_status.user_present = True
            self.system_status.last_activity_time = time.time()
            
            logger.debug(f"📊 坐姿数据: {posture_data.status}, 得分: {posture_data.combined_score:.1f}")
            
        except Exception as e:
            logger.error(f"❌ 处理坐姿数据异常: {e}")
    
    async def handle_voice_input(self, text: str):
        """处理语音输入"""
        try:
            if not text or len(text.strip()) == 0:
                return
            
            start_time = time.time()
            
            # 构建上下文
            context = {
                'posture_score': self.posture_history[-1].combined_score if self.posture_history else 0,
                'study_time': (time.time() - self.current_session.start_time) / 60 if self.current_session else 0,
                'warnings': self.system_status.posture_warnings
            }
            
            # AI对话
            ai_response = self.ai_engine.chat_with_ai(text, context)
            
            response_time = time.time() - start_time
            
            # 记录交互
            interaction = VoiceInteraction(
                session_id=self.current_session.session_id if self.current_session else 'no_session',
                user_input=text,
                ai_response=ai_response,
                confidence=0.9,  # 简化实现
                timestamp=time.time(),
                response_time=response_time
            )
            
            self.voice_interactions.append(interaction)
            self.db_manager.save_voice_interaction(interaction)
            
            # 发送响应
            self.hardware_comm.send_voice_response(ai_response)
            
            # 更新统计
            self.system_status.voice_interactions += 1
            
            logger.info(f"🎤 语音交互: {text[:30]}... → {ai_response[:30]}...")
            
        except Exception as e:
            logger.error(f"❌ 处理语音输入异常: {e}")
            error_response = "抱歉，我暂时无法理解您的问题。"
            self.hardware_comm.send_voice_response(error_response)
    
    def handle_button_press(self, button: str):
        """处理按键按下"""
        logger.info(f"🔘 按键按下: {button}")
        
        if button == 'function':
            if self.current_session is None:
                self.start_new_session()
            else:
                asyncio.create_task(self.send_personalized_advice())
        elif button == 'calibration':
            self.calibrate_system()
        elif button == 'reset':
            if self.current_session:
                self.end_current_session()
    
    def handle_system_status_update(self, data: Dict):
        """处理系统状态更新"""
        self.system_status.wifi_connected = data.get('wifi_connected', False)
        logger.debug("📊 系统状态已更新")
    
    def start_new_session(self):
        """开始新会话"""
        if self.current_session:
            self.end_current_session()
        
        session_id = f"session_{int(time.time())}"
        self.current_session = StudySession(
            session_id=session_id,
            start_time=time.time(),
            end_time=0,
            duration=0,
            posture_warnings=0,
            voice_interactions=0,
            average_posture_score=0,
            fatigue_events=0,
            break_recommendations=0
        )
        
        self.system_status.current_session_id = session_id
        self.system_status.session_start_time = time.time()
        self.system_status.posture_warnings = 0
        self.system_status.voice_interactions = 0
        
        logger.info(f"🎓 开始新学习会话: {session_id}")
        
        # 发送欢迎消息
        welcome_message = "学习会话已开始，祝您学习愉快！我会监控您的坐姿并提供建议。"
        self.hardware_comm.send_voice_response(welcome_message)
    
    def end_current_session(self):
        """结束当前会话"""
        if not self.current_session:
            return
        
        # 更新会话数据
        self.current_session.end_time = time.time()
        self.current_session.duration = self.current_session.end_time - self.current_session.start_time
        self.current_session.posture_warnings = self.system_status.posture_warnings
        self.current_session.voice_interactions = self.system_status.voice_interactions
        
        # 计算平均坐姿得分
        if self.posture_history:
            scores = [p.combined_score for p in self.posture_history]
            self.current_session.average_posture_score = sum(scores) / len(scores)
        
        # 保存会话
        self.db_manager.save_study_session(self.current_session)
        
        # 生成会话总结
        summary = self.generate_session_summary(self.current_session)
        
        logger.info(f"🎓 结束学习会话: {self.current_session.session_id}")
        logger.info(f"📊 会话总结: {summary}")
        
        # 发送结束消息
        end_message = f"学习会话已结束。{summary} 感谢使用智能学习桌！"
        self.hardware_comm.send_voice_response(end_message)
        
        # 清理状态
        self.current_session = None
        self.system_status.current_session_id = ""
        self.posture_history.clear()
        self.voice_interactions.clear()
    
    def generate_session_summary(self, session: StudySession) -> str:
        """生成会话总结"""
        duration_minutes = session.duration / 60
        
        if duration_minutes < 5:
            return f"学习时长{duration_minutes:.1f}分钟，时间较短。"
        elif session.average_posture_score >= 80:
            return f"学习时长{duration_minutes:.1f}分钟，坐姿优秀(平均{session.average_posture_score:.1f}分)。"
        elif session.average_posture_score >= 60:
            return f"学习时长{duration_minutes:.1f}分钟，坐姿良好(平均{session.average_posture_score:.1f}分)。"
        else:
            return f"学习时长{duration_minutes:.1f}分钟，坐姿需要改善(平均{session.average_posture_score:.1f}分)。"
    
    def should_give_warning(self) -> bool:
        """判断是否应该给出警告"""
        current_time = time.time()
        return (current_time - self.last_warning_time) >= self.config.WARNING_COOLDOWN
    
    async def send_posture_warning(self, posture_data: PostureData):
        """发送坐姿警告"""
        self.last_warning_time = time.time()
        self.system_status.posture_warnings += 1
        
        # 生成智能警告消息
        warning_message = self.generate_smart_warning(posture_data)
        
        # 发送到硬件
        self.hardware_comm.send_warning("posture", warning_message)
        
        # 发送到微信小程序
        await self.wechat_interface.send_warning("posture", warning_message, posture_data.suggestions)
        
        logger.warning(f"⚠️ 坐姿警告: {warning_message}")
    
    def generate_smart_warning(self, posture_data: PostureData) -> str:
        """生成智能警告消息"""
        base_message = f"检测到坐姿{posture_data.status}"
        
        if posture_data.issues:
            issues_text = "、".join(posture_data.issues[:2])  # 最多显示2个问题
            base_message += f"，主要问题：{issues_text}"
        
        if posture_data.suggestions:
            suggestion = posture_data.suggestions[0]  # 使用第一个建议
            base_message += f"。建议：{suggestion}"
        
        return base_message
    
    async def send_personalized_advice(self):
        """发送个性化建议"""
        try:
            # 获取用户统计数据
            user_stats = self.db_manager.get_user_statistics('default', 7)
            
            # 分析坐姿趋势
            posture_trend = self.ai_engine.analyze_posture_trend(list(self.posture_history))
            
            # 生成个性化建议
            advice_list = self.ai_engine.generate_personalized_advice(user_stats, posture_trend)
            
            # 发送建议
            advice_message = "根据您的学习数据分析，为您提供以下建议：" + "；".join(advice_list[:3])
            self.hardware_comm.send_voice_response(advice_message)
            
            logger.info(f"💡 个性化建议: {advice_message}")
            
        except Exception as e:
            logger.error(f"❌ 生成个性化建议异常: {e}")
    
    def calibrate_system(self):
        """校准系统"""
        logger.info("🔧 开始系统校准...")
        
        # 发送校准命令到硬件
        self.hardware_comm.send_command("CALIBRATE")
        
        # 校准摄像头检测器
        if self.camera_detector:
            # 这里应该实现摄像头校准逻辑
            pass
        
        calibration_message = "系统校准完成，请保持当前姿势作为标准坐姿。"
        self.hardware_comm.send_voice_response(calibration_message)
        
        logger.info("✅ 系统校准完成")
    
    def update_system_status(self):
        """更新系统状态"""
        current_time = time.time()
        
        # 更新学习时间
        if self.current_session:
            self.system_status.total_study_time = current_time - self.current_session.start_time
        
        # 检查用户是否在座
        if self.posture_history and current_time - self.posture_history[-1].timestamp > 30:
            self.system_status.user_present = False
    
    def check_session_timeout(self):
        """检查会话超时"""
        if not self.current_session:
            return
        
        current_time = time.time()
        if (current_time - self.system_status.last_activity_time) > self.config.SESSION_TIMEOUT:
            logger.info("⏰ 会话超时，自动结束当前会话")
            self.end_current_session()
    
    def generate_hourly_report(self):
        """生成小时报告"""
        if not self.current_session:
            return
        
        logger.info("📊 生成小时报告...")
        
        # 计算小时统计
        current_time = time.time()
        hour_start = current_time - 3600  # 过去1小时
        
        # 过滤过去1小时的坐姿数据
        hour_postures = [p for p in self.posture_history if p.timestamp >= hour_start]
        
        if hour_postures:
            avg_score = sum(p.combined_score for p in hour_postures) / len(hour_postures)
            warnings = sum(1 for p in hour_postures if p.need_warning)
            
            report = f"过去一小时平均坐姿得分{avg_score:.1f}分，共{warnings}次提醒。"
            
            if avg_score >= 80:
                report += "表现优秀，请继续保持！"
            elif avg_score >= 60:
                report += "总体良好，稍作调整会更好。"
            else:
                report += "需要改善坐姿，建议适当休息调整。"
            
            self.hardware_comm.send_voice_response(report)
            logger.info(f"📊 小时报告: {report}")
    
    def generate_daily_report(self):
        """生成日报"""
        logger.info("📊 生成日报...")
        
        # 获取今日统计
        user_stats = self.db_manager.get_user_statistics('default', 1)
        
        # 生成健康报告并保存到数据库
        # 这里可以添加更详细的报告生成逻辑
        
        logger.info("✅ 日报生成完成")
    
    def backup_data(self):
        """备份数据"""
        current_time = time.time()
        if current_time - self.last_backup_time < self.config.BACKUP_INTERVAL:
            return
        
        try:
            # 创建备份目录
            backup_dir = f"backups/{datetime.now().strftime('%Y%m%d_%H%M%S')}"
            os.makedirs(backup_dir, exist_ok=True)
            
            # 备份数据库
            import shutil
            shutil.copy2(self.config.DATABASE_PATH, f"{backup_dir}/smart_desk.db")
            
            self.last_backup_time = current_time
            logger.info(f"💾 数据备份完成: {backup_dir}")
            
        except Exception as e:
            logger.error(f"❌ 数据备份失败: {e}")
    
    def cleanup_old_data(self):
        """清理过期数据"""
        try:
            # 删除30天前的详细记录
            cutoff_time = time.time() - (30 * 24 * 3600)
            
            with sqlite3.connect(self.config.DATABASE_PATH) as conn:
                cursor = conn.cursor()
                
                # 清理过期的坐姿记录
                cursor.execute('DELETE FROM posture_records WHERE timestamp < ?', (cutoff_time,))
                
                # 清理过期的语音交互记录
                cursor.execute('DELETE FROM voice_interactions WHERE timestamp < ?', (cutoff_time,))
                
                # 清理过期的系统日志
                cursor.execute('DELETE FROM system_logs WHERE timestamp < ?', (cutoff_time,))
                
                conn.commit()
            
            logger.info("🧹 过期数据清理完成")
            
        except Exception as e:
            logger.error(f"❌ 数据清理失败: {e}")
    
    async def stop(self):
        """停止系统"""
        logger.info("🛑 正在停止智能学习桌系统...")
        
        self.running = False
        
        # 结束当前会话
        if self.current_session:
            self.end_current_session()
        
        # 停止摄像头检测
        if self.camera_detector:
            self.camera_detector.stop_detection()
        
        # 关闭连接
        if self.hardware_comm.connected:
            self.hardware_comm.serial_connection.close()
        
        if self.wechat_interface.connected:
            await self.wechat_interface.websocket.close()
        
        # 最终数据备份
        self.backup_data()
        
        logger.info("✅ 智能学习桌系统已停止")

# ========== 主程序入口 ==========
async def main():
    """主程序"""
    logger.info("🚀 启动AIOT智能学习桌完整系统...")
    
    try:
        # 创建系统配置
        config = SystemConfig()
        
        # 创建主系统
        smart_desk = SmartDeskSystem(config)
        
        # 启动系统
        if await smart_desk.start():
            logger.info("✅ 系统运行中，按 Ctrl+C 停止...")
            
            try:
                while True:
                    await asyncio.sleep(1)
            except KeyboardInterrupt:
                logger.info("📋 收到停止信号...")
        
        # 停止系统
        await smart_desk.stop()
        
    except Exception as e:
        logger.error(f"❌ 系统异常: {e}")
    
    logger.info("👋 AIOT智能学习桌系统已退出")

if __name__ == "__main__":
    # 确保必要的目录存在
    os.makedirs("logs", exist_ok=True)
    os.makedirs("data", exist_ok=True)
    os.makedirs("backups", exist_ok=True)
    
    # 运行主程序
    asyncio.run(main())
